// $ANTLR 3.0.1 /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g 2008-04-25 02:05:00

package blms.util.expression;

import org.antlr.runtime.BitSet;
import org.antlr.runtime.NoViableAltException;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.antlr.runtime.tree.TreeNodeStream;
import org.antlr.runtime.tree.TreeParser;

import blms.domain.Expression.Context;
import blms.exception.UnknownVariableException;

public class Evaluator extends TreeParser {
	public static final String[] tokenNames = new String[] { "<invalid>",
			"<EOR>", "<DOWN>", "<UP>", "NEWLINE", "INT", "ID", "WS", "'+'",
			"'-'", "'*'", "'/'", "'('", "')'" };
	public static final int WS = 7;
	public static final int NEWLINE = 4;
	public static final int INT = 5;
	public static final int ID = 6;
	public static final int EOF = -1;

	public Evaluator(final TreeNodeStream input) {
		super(input);
	}

	@Override
	public String[] getTokenNames() {
		return tokenNames;
	}

	@Override
	public String getGrammarFileName() {
		return "/data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g";
	}

	/** Map variable name to Integer object holding value */
	private Context context;

	/** Set up an evaluator with a node stream; and a context */
	public Evaluator(final CommonTreeNodeStream nodes, final Context context) {
		this(nodes);
		this.context = context;
	}

	// $ANTLR start eval
	// /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g:24:1: eval
	// returns [int value] : expr ;
	public final int eval() throws RecognitionException {
		final int value = 0;

		int expr1 = 0;

		try {
			// /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g:25:5:
			// ( expr )
			// /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g:25:8:
			// expr
			{
				pushFollow(FOLLOW_expr_in_eval56);
				expr1 = expr();
				_fsp--;

				return expr1;

			}

		} catch (final RecognitionException re) {
			reportError(re);
			recover(input, re);
		} finally {
		}
		return value;
	}

	// $ANTLR end eval

	// $ANTLR start expr
	// /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g:28:1: expr
	// returns [int value] : ( ^( '+' a= expr b= expr ) | ^( '-' a= expr b= expr
	// ) | ^( '*' a= expr b= expr ) | ^( '/' a= expr b= expr ) | ID | INT );
	public final int expr() throws RecognitionException {
		int value = 0;

		CommonTree ID2 = null;
		CommonTree INT3 = null;
		int a = 0;

		int b = 0;

		try {
			// /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g:29:5:
			// ( ^( '+' a= expr b= expr ) | ^( '-' a= expr b= expr ) | ^( '*' a=
			// expr b= expr ) | ^( '/' a= expr b= expr ) | ID | INT )
			int alt1 = 6;
			switch (input.LA(1)) {
			case 8: {
				alt1 = 1;
			}
				break;
			case 9: {
				alt1 = 2;
			}
				break;
			case 10: {
				alt1 = 3;
			}
				break;
			case 11: {
				alt1 = 4;
			}
				break;
			case ID: {
				alt1 = 5;
			}
				break;
			case INT: {
				alt1 = 6;
			}
				break;
			default:
				final NoViableAltException nvae = new NoViableAltException(
						"28:1: expr returns [int value] : ( ^( '+' a= expr b= expr ) | ^( '-' a= expr b= expr ) | ^( '*' a= expr b= expr ) | ^( '/' a= expr b= expr ) | ID | INT );",
						1, 0, input);

				throw nvae;
			}

			switch (alt1) {
			case 1:
				// /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g:29:9:
					// ^( '+' a= expr b= expr )
			{
				match(input, 8, FOLLOW_8_in_expr82);

				match(input, Token.DOWN, null);
				pushFollow(FOLLOW_expr_in_expr86);
				a = expr();
				_fsp--;

				pushFollow(FOLLOW_expr_in_expr90);
				b = expr();
				_fsp--;

				match(input, Token.UP, null);
				value = a + b;

			}
				break;
			case 2:
				// /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g:30:9:
					// ^( '-' a= expr b= expr )
			{
				match(input, 9, FOLLOW_9_in_expr105);

				match(input, Token.DOWN, null);
				pushFollow(FOLLOW_expr_in_expr109);
				a = expr();
				_fsp--;

				pushFollow(FOLLOW_expr_in_expr113);
				b = expr();
				_fsp--;

				match(input, Token.UP, null);
				value = a - b;

			}
				break;
			case 3:
				// /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g:31:9:
					// ^( '*' a= expr b= expr )
			{
				match(input, 10, FOLLOW_10_in_expr131);

				match(input, Token.DOWN, null);
				pushFollow(FOLLOW_expr_in_expr135);
				a = expr();
				_fsp--;

				pushFollow(FOLLOW_expr_in_expr139);
				b = expr();
				_fsp--;

				match(input, Token.UP, null);
				value = a * b;

			}
				break;
			case 4:
				// /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g:32:9:
					// ^( '/' a= expr b= expr )
			{
				match(input, 11, FOLLOW_11_in_expr154);

				match(input, Token.DOWN, null);
				pushFollow(FOLLOW_expr_in_expr158);
				a = expr();
				_fsp--;

				pushFollow(FOLLOW_expr_in_expr162);
				b = expr();
				_fsp--;

				match(input, Token.UP, null);
				value = a / b;

			}
				break;
			case 5:
				// /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g:33:9:
					// ID
			{
				ID2 = (CommonTree) input.LT(1);
				match(input, ID, FOLLOW_ID_in_expr176);

				final String variable = ID2.getText();
				final Integer v = context.getVariable(variable);
				if (v != null) {
					value = v.intValue();
				} else {
					throw new UnknownVariableException();
				}

			}
				break;
			case 6:
				// /data/workspace/silibrina-snooker/src/main/antlr/Evaluator.g:43:9:
					// INT
			{
				INT3 = (CommonTree) input.LT(1);
				match(input, INT, FOLLOW_INT_in_expr196);
				value = Integer.valueOf(INT3.getText());

			}
				break;

			}
		} catch (final RecognitionException re) {
			reportError(re);
			recover(input, re);
		} finally {
		}
		return value;
	}

	// $ANTLR end expr

	public static final BitSet FOLLOW_expr_in_eval56 = new BitSet(
			new long[] { 0x0000000000000002L });
	public static final BitSet FOLLOW_8_in_expr82 = new BitSet(
			new long[] { 0x0000000000000004L });
	public static final BitSet FOLLOW_expr_in_expr86 = new BitSet(
			new long[] { 0x0000000000000F60L });
	public static final BitSet FOLLOW_expr_in_expr90 = new BitSet(
			new long[] { 0x0000000000000008L });
	public static final BitSet FOLLOW_9_in_expr105 = new BitSet(
			new long[] { 0x0000000000000004L });
	public static final BitSet FOLLOW_expr_in_expr109 = new BitSet(
			new long[] { 0x0000000000000F60L });
	public static final BitSet FOLLOW_expr_in_expr113 = new BitSet(
			new long[] { 0x0000000000000008L });
	public static final BitSet FOLLOW_10_in_expr131 = new BitSet(
			new long[] { 0x0000000000000004L });
	public static final BitSet FOLLOW_expr_in_expr135 = new BitSet(
			new long[] { 0x0000000000000F60L });
	public static final BitSet FOLLOW_expr_in_expr139 = new BitSet(
			new long[] { 0x0000000000000008L });
	public static final BitSet FOLLOW_11_in_expr154 = new BitSet(
			new long[] { 0x0000000000000004L });
	public static final BitSet FOLLOW_expr_in_expr158 = new BitSet(
			new long[] { 0x0000000000000F60L });
	public static final BitSet FOLLOW_expr_in_expr162 = new BitSet(
			new long[] { 0x0000000000000008L });
	public static final BitSet FOLLOW_ID_in_expr176 = new BitSet(
			new long[] { 0x0000000000000002L });
	public static final BitSet FOLLOW_INT_in_expr196 = new BitSet(
			new long[] { 0x0000000000000002L });

}